#!/bin/python

import string,cgi,time,os
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer

class PowerInfo:
  class ProcessorInfo:
    def __init__(self, name):
      self.name = name
      self.state = None
      self.allStates = []
    def moveToState(self, stateStr):
      print "'%s' is going to state: '%s', type:\necho %s | sudo tee %s" % (self.name, stateStr, stateStr, os.path.join("/proc/acpi/processor", self.name, "throttling"))
  def __init__(self):
    self.ionIsOn = None
    self.processorInfos = []
  def fillInfo(self):
    os.system("/opt/acpi_call/asus1215n.sh > /tmp/powerstate.txt")
    buf = open("/tmp/powerstate.txt").read()
    pref = "appears to be "
    p = buf.find(pref)
    if p > -1:
      p += len(pref)
      state = buf[p:]
      print "ion state is: '%s'" % state
      if state in ["on", "of"]:
        self.ionIsOn = state == "on"
    processorsRoot = "/proc/acpi/processor"
    if os.path.exists(processorsRoot):
      proseccors = os.listdir(processorsRoot)
      proseccors.sort()
      for procName in proseccors:
        procPath = os.path.join(processorsRoot, procName, "throttling")
        buf = open(procPath).read()
        pref = "states:\n"
        p = buf.find(pref)
        if p == -1: continue;
        p += len(pref)
        buf = buf[p:]
        activeState = "?"
        pinfo = PowerInfo.ProcessorInfo(procName)
        for stateStr in buf.split("\n"):
          pref = "T"
          isActive = stateStr.find("*" + pref) > -1
          p = stateStr.find(pref)
          if p > -1:
            stateStr = stateStr[p:]
            p = stateStr.find(":")
            if p == -1: p = len(buf);
            stateStr = stateStr[:p]
            if isActive: activeState = stateStr
            pinfo.allStates.append(stateStr)
        pinfo.state = activeState
        self.processorInfos.append(pinfo)

class PowerstateHandler(BaseHTTPRequestHandler):
  def __initRootMap(self):
    self.__rootmap = {
      "powerstate": PowerstateHandler.__powerstate
    }
    
  def __getPath(self):
    path = self.path.split("/")
    while len(path) > 0 and len(path[0]) == 0:
      path = path[1:]
    return path

  class Args:
    def __init__(self):
      self.cmd = None

  def __getArgs(self, path):
    print path
    result = PowerstateHandler.Args()
    if len(path) == 0:
      return result
    src = path[0]
    while len(src) > 0 and src[0] == '?':
      src = src[1:]
    for descr in src.split("&"):
      src = src.split("=")
      if len(src) == 2:
        k, v = src
        result.__dict__[k] = v
    return result

  def __powerstate(self, path):
    args = self.__getArgs(path)
    self.wfile.write("<html>")
    self.wfile.write("POWERSTATE<br><br><br>")
    if args.cmd is not None:
      self.wfile.write("Command is: '%s'<br><br>" % args.cmd)
    pinfo = PowerInfo()
    pinfo.fillInfo()
    if args.cmd == "make_powersafe":
      for pi in pinfo.processorInfos:
        pi.moveToState(pi.allStates[-1:][0])
    if args.cmd.startswith("make_performance"):
      for pi in pinfo.processorInfos:
        pi.moveToState(pi.allStates[0])
    batteriesRoot = "/proc/acpi/battery"
    batteries = os.listdir(batteriesRoot)
    for battery in batteries:
      state = os.path.join(batteriesRoot, battery, "state")
      state = open(state).read()
      pref = "present:"
      p = state.find(pref)
      if p > -1:
        p += len(pref)
        buf = state[p:]
        while len(buf) > 0 and buf[0] in [" ", "\t", "\n"]: buf = buf[1:];
        pref = "\n"
        p = buf.find(pref)
        if  p == -1: p = len(buf);
        presented = buf[:p]
        presented = presented == "yes"
      else:
        presented = True
      if presented:
        self.wfile.write(battery)
        self.wfile.write("<br>")
        self.wfile.write(state.replace("\n", "<br>"))
        self.wfile.write("<br><br><br>")
    ionstatescript = "/opt/acpi_call/asus1215n.sh"
    if os.path.exists(ionstatescript):
      os.system(ionstatescript + " > /tmp/powerstate.txt")
      self.wfile.write(open("/tmp/powerstate.txt").read().replace("\n", "<br>"))
      self.wfile.write("<a href='/powerstate/?cmd=switch_ion_off'>Switch off NVIDIA ION</a>")
      self.wfile.write("<br><br><br>")
    self.wfile.write("<a href='/powerstate/?cmd=make_powersafe'>powersafe</a><br>")
    self.wfile.write("<a href='/powerstate/?cmd=make_performance_no_gpu'>performanceA<small> (no ion gpu)</small></a><br>")
    self.wfile.write("<a href='/powerstate/?cmd=make_performance_ion_gpu'>performanceB<small> (+ion gpu)</small></a><br>")
    self.wfile.write("<table summary='power-state-info' border='2' cellspacing='1'>")
    self.wfile.write("<tr>")
    self.wfile.write("<td colspan='%i'>" % (1 + len(pinfo.processorInfos)))
    self.wfile.write("<b><br>unit states</b>")
    self.wfile.write("</td>")
    self.wfile.write("</tr>")
    self.wfile.write("<tr>")
    self.wfile.write("<td>")
    self.wfile.write("gpu")
    self.wfile.write("</td>")
    for pi in pinfo.processorInfos:
      self.wfile.write("<td>")
      self.wfile.write(pi.name)
      self.wfile.write("</td>")
    self.wfile.write("</tr>")
    self.wfile.write("<tr>")
    self.wfile.write("<td>")
    if pinfo.ionIsOn is None:
      self.wfile.write("None")
    else:
      if pinfo.ionIsOn:
        self.wfile.write("on")
      else:
        self.wfile.write("off")
    self.wfile.write("</td>")
    for pi in pinfo.processorInfos:
      self.wfile.write("<td>")
      self.wfile.write(pi.state + "<br>(%s)" % ",".join(pi.allStates))
      self.wfile.write("</td>")
    self.wfile.write("</tr>")
    self.wfile.write("</table>")
    self.wfile.write("</html>")

  def do_GET(self):
    self.__initRootMap()
    path = self.__getPath()
    if len(path) == 0:
      self.wfile.write("Bad address: " + self.path)
      return
    root = path[0]
    if root not in self.__rootmap.keys():
      self.wfile.write("Bad root: " + root)
      return
    subhandler = self.__rootmap[root]
    subhandler(self, path[1:])

  def do_POST(self):
    pass

def main():
  try:
    server = HTTPServer(('', 1991), PowerstateHandler)
    print 'started httpserver...'
    server.serve_forever()
  except KeyboardInterrupt:
    print '^C received, shutting down server'
    server.socket.close()

if __name__ == '__main__':
  main()
